/* modularity_mat.h */

#ifndef _MODULARITY_MAT_H_
#define _MODULARITY_MAT_H_

#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "sparse_matrix.h"

/* 
 *	Creates modularity matrix from the given adjacency matrix A
 *	-----------------------------------------------------------
 *	A:		The adjacency matrix
 *	return:	The desired modularity matrix
 *	------------------------------------------------------------
 *	(!) The user is responsible of releasing the returned matrix
 */
elem** create_modularity_mat(sparse_matrix_lst* A);

/* 
 *	Calculates the degree of each node
 *	----------------------------------
 *	A:		The adjacency matrix
 *	return:	The vector that specifies the degree of each node
 */
elem* calc_nodes_degrees(sparse_matrix_lst* A);

/* 
 *	Calculates the degree of a single node
 *	--------------------------------------
 *	A:		 The adjacency matrix
 *	nodeInd: The node we want to calculate the degree for
 *	return:	 The desired node's degree
 */
elem calc_node_degree(sparse_matrix_lst* A, int nodeInd);

/* 
 *	Counts the edges in a given graph (each edge is counted twice)
 *	--------------------------------------------------------------
 *	nodes_degrees:	The vector that specifies each node's degree
 *	size:			The vector's size
 *	return:			The nodes' degrees sum (twice the edges number)
 */
elem count_edges(elem* nodes_degrees, int size);

/* 
 *	Creates f(g) from a given B[g]
 *	------------------------------
 *	B:			 The modularity matrix
 *	g:			 The indices subgroup
 *	n:			 The modularity matrix size
 *	elements_no: The elements number in the sparse matrix row	 
 *	------------------------------------------------------------
 *	(!) The user is responsible of releasing the returned vector
 */
elem* create_f(elem** B, int* g, int n, int elements_no);

/* 
 *	Creates generalized modularity matrix
 *	-------------------------------------
 *	B:			 The modularity matrix
 *	g:			 The indices subgroup
 *	elements_no: The elements number in the sparse matrix row
 *	f:			 The vector that specifies the sum of B[g](i,j)
 *	n:			 The modularity matrix size
 *	-----------------------------------------------------------
 *  (!)The user is responsible of releasing the returned matrix
 */
elem** create_generalized_modularity_matrix(elem** B, int* g, int elements_no,
											elem* f, int n);

/*
 *	Retrieves sub matrix from B according to the given list of nodes (g)
 *	--------------------------------------------------------------------
 *	
 *  The user is responsible of releasing the returned matrix */
/* void print_B_g(elem** B, int* g, int elements_no);*/

/* 
 *	Allocates memory for an n sized matrix
 *	--------------------------------------
 *	size:	The size we need to allocate for the matrix
 *	return:	The allocated matrix pointer
 */
elem** allocate_matrix(int n);

/* 
 *	frees the allocated memory of a given matrix
 *	--------------------------------------------
 *	matrix:	The memory of the matrix we want to free
 *	n:		The matrix size
 */
void free_matrix(elem** matrix, int n);

/* 
 *	Prints a given matrix
 *	---------------------
 *	matrix:	The matrix that we want to print
 *	n:		The matrix size
 */
void print_matrix(elem** matrix, int n);

/*
 *	Reads the cells of the matrix from a given file
 *	-----------------------------------------------
 *	file_name:	The file from which we read the adjacency matrix
 *	return:		A pointer to a sparse adjacency matrix
 */
sparse_matrix_lst* read_adjacency_matrix(char* file_name);

/*
 *	Reads a group of indices from a given file and returns the elements number
 *	--------------------------------------------------------------------------
 *	file_name:	The file from which we read the group indices
 *	g:			The indices subgroup
 *	return:		The elements number in g
 */
int read_group_file(char* file_name, int* g);

#endif /*_MODULARITY_MAT_H_*/
